#include "drv_usart1.h"
#include "drv_timer.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "drv_pin.h"
#include "main.h"
#include "delay.h"
#include "systemdata.h"

static UsartRxInfo_t rxInfo[4] = {{.timeout_flag = 0,.timeout_cnt = 0,.recv_ok_flag = 0,.recv_len = 0,.recv_buf = {0}}};
static Timer_t *rx_ok_timer = NULL;
UsartRxInfo_t *get_uart1_info(void){
	return &rxInfo[0];
}

UsartRxInfo_t *get_uart2_info(void){
	return &rxInfo[1];
}

UsartRxInfo_t *get_uart4_info(void){
	return &rxInfo[3];
}


void usart1_send(uint8_t *buf,uint16_t len){
	hc32_pin_write(RS_485_EN_PIN,PIN_HIGH);
	Delay_ms(5);
	uint16_t i=0;
	for(i=0;i<len;i++){
		while (Reset == USART_GetStatus(M4_USART1, UsartTxEmpty));
		USART_SendData(M4_USART1,buf[i]);
//		printf("%02x,",buf[i]);
	}
//	printf("\n");
	Delay_ms(10);
	hc32_pin_write(RS_485_EN_PIN,PIN_LOW);
}

void usart2_send(uint8_t *buf,uint16_t len){
	uint16_t i=0;
	for(i=0;i<len;i++){
		while (Reset == USART_GetStatus(M4_USART2, UsartTxEmpty));
		USART_SendData(M4_USART2,buf[i]);
	}
}

void usart4_send(uint8_t *buf,uint16_t len){
	hc32_pin_write(RS_485_EN_PIN,PIN_HIGH);
	Delay_ms(5);
	uint16_t i=0;
	for(i=0;i<len;i++){
		while (Reset == USART_GetStatus(M4_USART4, UsartTxEmpty));
		USART_SendData(M4_USART4,buf[i]);
	}
	Delay_ms(10);
	hc32_pin_write(RS_485_EN_PIN,PIN_LOW);
}

static void uart_rx_ok_callback(void *data){
	if(rxInfo[0].recv_ok_flag == 0){
		if(rxInfo[0].timeout_cnt ++  > 20){
			rxInfo[0].timeout_cnt = 0;
			if(rxInfo[0].recv_len > 0){
				rxInfo[0].recv_buf[rxInfo[0].recv_len] = '\0';
				rxInfo[0].recv_ok_flag = 1;
			}
		}
	}
	if(rxInfo[1].recv_ok_flag == 0){
		if(rxInfo[1].timeout_cnt ++  > 20){
			rxInfo[1].timeout_cnt = 0;
			if(rxInfo[1].recv_len > 0){
				rxInfo[1].recv_buf[rxInfo[1].recv_len] = '\0';
				rxInfo[1].recv_ok_flag = 1;
			}
		}
	}
	if(rxInfo[3].recv_ok_flag == 0){
		if(rxInfo[3].timeout_cnt ++  > 20){
			rxInfo[3].timeout_cnt = 0;
			if(rxInfo[3].recv_len > 0){
				rxInfo[3].recv_buf[rxInfo[3].recv_len] = '\0';
				rxInfo[3].recv_ok_flag = 1;
			}
		}
	}
}

void uart1_rx_callback(void){
	uint16_t u16Data = USART_RecData(M4_USART1);
	if(rxInfo[0].recv_ok_flag == 0){
		if(rxInfo[0].recv_len < USART_RX_BUF_SIZE - 1){
			rxInfo[0].recv_buf[rxInfo[0].recv_len ++] = (uint8_t )u16Data;
		}else{
			rxInfo[0].recv_ok_flag = 1;
		}
	}
	rxInfo[0].timeout_cnt = 0;
	USART_ClearStatus(M4_USART1, UsartRxNoEmpty);
}

void uart2_rx_callback(void){
	uint16_t u16Data = USART_RecData(M4_USART2);
	if(rxInfo[1].recv_ok_flag == 0){
		if(rxInfo[1].recv_len < USART_RX_BUF_SIZE - 1){
			rxInfo[1].recv_buf[rxInfo[1].recv_len ++] = (uint8_t )u16Data;
		}else{
			rxInfo[1].recv_ok_flag = 1;
		}
	}
	rxInfo[1].timeout_cnt = 0;
	USART_ClearStatus(M4_USART2, UsartRxNoEmpty);
	USART_FuncCmd(M4_USART2, UsartTxAndTxEmptyInt, Enable);
}

void uart4_rx_callback(void){
	uint16_t u16Data = USART_RecData(M4_USART4);
	if(rxInfo[3].recv_ok_flag == 0){
		if(rxInfo[3].recv_len < USART_RX_BUF_SIZE - 1){
			rxInfo[3].recv_buf[rxInfo[3].recv_len ++] = (uint8_t )u16Data;
		}else{
			rxInfo[3].recv_ok_flag = 1;
		}
	}
	rxInfo[3].timeout_cnt = 0;
	USART_ClearStatus(M4_USART4, UsartRxNoEmpty);
	USART_FuncCmd(M4_USART4, UsartTxAndTxEmptyInt, Enable);
}

static void uart1_error_callback(void){
    if (Set == USART_GetStatus(M4_USART1, UsartFrameErr)){
        USART_ClearStatus(M4_USART1, UsartFrameErr);
    }
    if (Set == USART_GetStatus(M4_USART1, UsartParityErr)){
        USART_ClearStatus(M4_USART1, UsartParityErr);
    }
    if (Set == USART_GetStatus(M4_USART1, UsartOverrunErr)){
        USART_ClearStatus(M4_USART1, UsartOverrunErr);
    }
}

static void uart2_error_callback(void){
    if (Set == USART_GetStatus(M4_USART2, UsartFrameErr)){
        USART_ClearStatus(M4_USART2, UsartFrameErr);
    }
    if (Set == USART_GetStatus(M4_USART2, UsartParityErr)){
        USART_ClearStatus(M4_USART2, UsartParityErr);
    }
    if (Set == USART_GetStatus(M4_USART2, UsartOverrunErr)){
        USART_ClearStatus(M4_USART2, UsartOverrunErr);
    }
}

static void uart4_error_callback(void){
    if (Set == USART_GetStatus(M4_USART4, UsartFrameErr)){
        USART_ClearStatus(M4_USART4, UsartFrameErr);
    }
    if (Set == USART_GetStatus(M4_USART4, UsartParityErr)){
        USART_ClearStatus(M4_USART4, UsartParityErr);
    }
    if (Set == USART_GetStatus(M4_USART4, UsartOverrunErr)){
        USART_ClearStatus(M4_USART4, UsartOverrunErr);
    }
}

void usart1_sleep_enter(void){
	stc_port_init_t stcPortInit;
	MEM_ZERO_STRUCT(stcPortInit);
	USART_DeInit(M4_USART1);
	stcPortInit.enPinMode = Pin_Mode_Out;
	stcPortInit.enPullUp = Disable;
	PORT_SetFunc(USART1_RX_PORT, USART1_RX_PIN, Func_Gpio, Disable);
	PORT_SetFunc(USART1_TX_PORT, USART1_TX_PIN, Func_Gpio, Disable);
	PORT_Init(USART1_RX_PORT, USART1_RX_PIN, &stcPortInit);
	PORT_Init(USART1_TX_PORT, USART1_TX_PIN, &stcPortInit);
	PORT_ResetBits(USART1_RX_PORT, USART1_RX_PIN);
	PORT_ResetBits(USART1_TX_PORT, USART1_TX_PIN);	
}

void usart2_sleep_enter(void){
	stc_port_init_t stcPortInit;
	MEM_ZERO_STRUCT(stcPortInit);
	USART_DeInit(M4_USART2);
	stcPortInit.enPinMode = Pin_Mode_Out;
    stcPortInit.enExInt = Enable;
    stcPortInit.enPullUp = Enable;
	PORT_SetFunc(USART2_RX_PORT, USART2_RX_PIN, Func_Gpio, Disable);
    PORT_SetFunc(USART2_TX_PORT, USART2_TX_PIN, Func_Gpio, Disable);
	PORT_Init(USART2_RX_PORT, USART2_RX_PIN, &stcPortInit);
	PORT_Init(USART2_TX_PORT, USART2_TX_PIN, &stcPortInit);
	PORT_ResetBits(USART2_RX_PORT, USART2_RX_PIN);
	PORT_ResetBits(USART2_TX_PORT, USART2_TX_PIN);
}

void usart4_sleep_enter(void){
	stc_port_init_t stcPortInit;
	MEM_ZERO_STRUCT(stcPortInit);
	USART_DeInit(M4_USART4);
	stcPortInit.enPinMode = Pin_Mode_Out;
    stcPortInit.enExInt = Enable;
    stcPortInit.enPullUp = Enable;
	PORT_SetFunc(USART4_RX_PORT, USART4_RX_PIN, Func_Gpio, Disable);
    PORT_SetFunc(USART4_TX_PORT, USART4_TX_PIN, Func_Gpio, Disable);
	PORT_Init(USART4_RX_PORT, USART4_RX_PIN, &stcPortInit);
	PORT_Init(USART4_TX_PORT, USART4_TX_PIN, &stcPortInit);
	PORT_ResetBits(USART4_RX_PORT, USART4_RX_PIN);
	PORT_ResetBits(USART4_TX_PORT, USART4_TX_PIN);
}

void usart1_init(uint32_t baud){
	hc32_pin_mode(RS_485_EN_PIN,PIN_MODE_OUTPUT);
	hc32_pin_write(RS_485_EN_PIN,PIN_LOW);
	stc_irq_regi_conf_t stcIrqRegiCfg;
	en_result_t enRet = Ok;
	const stc_usart_uart_init_t stcInitCfg = {
		UsartIntClkCkNoOutput,
		UsartClkDiv_4,
		UsartDataBits8,
		UsartDataLsbFirst,
		UsartOneStopBit,
		UsartParityNone,
		UsartSampleBit8,
		UsartStartBitFallEdge,
		UsartRtsEnable,
	};
	PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART1, Enable);
	PORT_SetFunc(USART1_RX_PORT, USART1_RX_PIN, Func_Usart1_Rx, Disable);
	PORT_SetFunc(USART1_TX_PORT, USART1_TX_PIN, Func_Usart1_Tx, Disable);
	while (USART_UART_Init(M4_USART1, &stcInitCfg) != Ok){
		printf("USART_UART_Init error\n");
	}
	/* Set baudrate */
	while (USART_SetBaudrate(M4_USART1, baud) != Ok){
		printf("USART_SetBaudrate error\n");
	}
	/* Set USART RX IRQ */
	stcIrqRegiCfg.enIRQn = Int003_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart1_rx_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART1_RI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/* Set USART RX error IRQ */
	stcIrqRegiCfg.enIRQn = Int004_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart1_error_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART1_EI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART1, UsartRx, Enable);	
	USART_FuncCmd(M4_USART1, UsartRxInt, Enable);
	USART_FuncCmd(M4_USART1, UsartTx, Enable);
	if(rx_ok_timer == NULL){
		rx_ok_timer = timer_create(uart_rx_ok_callback,1);
		while(rx_ok_timer == NULL){
			printf("rx_ok_timer create failed!\n");
			Delay_ms(1000);
		}
		timer_start(rx_ok_timer);
	}
}

void usart2_init(uint32_t baud){
	uint16_t u16RxData;
	stc_irq_regi_conf_t stcIrqRegiCfg;
	en_result_t enRet = Ok;
	const stc_usart_uart_init_t stcInitCfg = {
		UsartIntClkCkNoOutput,UsartClkDiv_4,UsartDataBits8,
		UsartDataLsbFirst,UsartOneStopBit,UsartParityNone,
		UsartSampleBit8,UsartStartBitFallEdge,UsartRtsEnable,
	};
	/* Enable peripheral clock */
	PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART2, Enable);
	/* Initialize USART IO */
	PORT_SetFunc(USART2_RX_PORT, USART2_RX_PIN, Func_Usart2_Rx, Disable);
	PORT_SetFunc(USART2_TX_PORT, USART2_TX_PIN, Func_Usart2_Tx, Disable);
	/* Initialize UART */
	while (USART_UART_Init(M4_USART2, &stcInitCfg) != Ok){
		printf("USART_UART_Init error\n");
	}
	/* Set baudrate */
	while (USART_SetBaudrate(M4_USART2, baud) != Ok){
		printf("USART_SetBaudrate error\n");
	}
	/* Set USART RX IRQ */
	stcIrqRegiCfg.enIRQn = Int006_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart2_rx_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART2_RI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/* Set USART RX error IRQ */
	stcIrqRegiCfg.enIRQn = Int007_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart2_error_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART2_EI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART2, UsartRx, Enable);
	USART_FuncCmd(M4_USART2, UsartTx, Enable);
	USART_FuncCmd(M4_USART2, UsartRxInt, Enable);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART2, UsartRx, Enable);	
	USART_FuncCmd(M4_USART2, UsartRxInt, Enable);
	USART_FuncCmd(M4_USART2, UsartTx, Enable);
	
	if(rx_ok_timer == NULL){
		rx_ok_timer = timer_create(uart_rx_ok_callback,1);
		while(rx_ok_timer == NULL){
			printf("rx_ok_timer create failed!\n");
			Delay_ms(1000);
		}
		timer_start(rx_ok_timer);
	}
}

static void usart4_default_init(void){
	getSysConfData()->zhixiangParam.serialPortBaudRate.value = 96;
	saveSysConfData();
	hc32_pin_mode(RS_485_EN_PIN,PIN_MODE_OUTPUT);
	hc32_pin_write(RS_485_EN_PIN,PIN_LOW);
	uint16_t u16RxData;
	stc_irq_regi_conf_t stcIrqRegiCfg;
	en_result_t enRet = Ok;
	const stc_usart_uart_init_t stcInitCfg = {
		UsartIntClkCkNoOutput,UsartClkDiv_4,UsartDataBits8,
		UsartDataLsbFirst,UsartOneStopBit,UsartParityNone,
		UsartSampleBit8,UsartStartBitFallEdge,UsartRtsEnable,
	};
	/* Enable peripheral clock */
	PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART4, Enable);
	/* Initialize USART IO */
	PORT_SetFunc(USART4_RX_PORT, USART4_RX_PIN, Func_Usart4_Rx, Disable);
	PORT_SetFunc(USART4_TX_PORT, USART4_TX_PIN, Func_Usart4_Tx, Disable);
	/* Initialize UART */
	while (USART_UART_Init(M4_USART4, &stcInitCfg) != Ok){
		printf("USART_UART_Init error\n");
	}
	/* Set baudrate */
	while (USART_SetBaudrate(M4_USART4, 9600) != Ok){
		printf("USART_SetBaudrate error\n");
	}
	/* Set USART RX IRQ */
	stcIrqRegiCfg.enIRQn = Int011_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart4_rx_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART4_RI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/* Set USART RX error IRQ */
	stcIrqRegiCfg.enIRQn = Int012_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart4_error_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART4_EI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART4, UsartRx, Enable);
	USART_FuncCmd(M4_USART4, UsartTx, Enable);
	USART_FuncCmd(M4_USART4, UsartRxInt, Enable);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART4, UsartRx, Enable);	
	USART_FuncCmd(M4_USART4, UsartRxInt, Enable);
	USART_FuncCmd(M4_USART4, UsartTx, Enable);
	
	if(rx_ok_timer == NULL){
		rx_ok_timer = timer_create(uart_rx_ok_callback,1);
		while(rx_ok_timer == NULL){
			printf("rx_ok_timer create failed!\n");
			Delay_ms(1000);
		}
		timer_start(rx_ok_timer);
	}
}

void usart4_init(uint32_t baud){
	hc32_pin_mode(RS_485_EN_PIN,PIN_MODE_OUTPUT);
	hc32_pin_write(RS_485_EN_PIN,PIN_LOW);
	uint16_t u16RxData;
	stc_irq_regi_conf_t stcIrqRegiCfg;
	en_result_t enRet = Ok;
	const stc_usart_uart_init_t stcInitCfg = {
		UsartIntClkCkNoOutput,UsartClkDiv_4,UsartDataBits8,
		UsartDataLsbFirst,UsartOneStopBit,UsartParityNone,
		UsartSampleBit8,UsartStartBitFallEdge,UsartRtsEnable,
	};
	/* Enable peripheral clock */
	PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART4, Enable);
	/* Initialize USART IO */
	PORT_SetFunc(USART4_RX_PORT, USART4_RX_PIN, Func_Usart4_Rx, Disable);
	PORT_SetFunc(USART4_TX_PORT, USART4_TX_PIN, Func_Usart4_Tx, Disable);
	/* Initialize UART */
	while (USART_UART_Init(M4_USART4, &stcInitCfg) != Ok){
		printf("USART_UART_Init error\n");
	}
	/* Set baudrate */
	while (USART_SetBaudrate(M4_USART4, baud) != Ok){
		printf("USART_SetBaudrate error,will set baudrate to 9600bps\n");
		usart4_default_init();
		return;
	}
	/* Set USART RX IRQ */
	stcIrqRegiCfg.enIRQn = Int011_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart4_rx_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART4_RI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/* Set USART RX error IRQ */
	stcIrqRegiCfg.enIRQn = Int012_IRQn;
	stcIrqRegiCfg.pfnCallback = &uart4_error_callback;
	stcIrqRegiCfg.enIntSrc = INT_USART4_EI;
	enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
	NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
	NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART4, UsartRx, Enable);
	USART_FuncCmd(M4_USART4, UsartTx, Enable);
	USART_FuncCmd(M4_USART4, UsartRxInt, Enable);
	/*Enable RX && TX function*/
	USART_FuncCmd(M4_USART4, UsartRx, Enable);	
	USART_FuncCmd(M4_USART4, UsartRxInt, Enable);
	USART_FuncCmd(M4_USART4, UsartTx, Enable);
	
	if(rx_ok_timer == NULL){
		rx_ok_timer = timer_create(uart_rx_ok_callback,1);
		while(rx_ok_timer == NULL){
			printf("rx_ok_timer create failed!\n");
			Delay_ms(1000);
		}
		timer_start(rx_ok_timer);
	}
}
